package com.wind.trademark.bill.service.impl;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.hibernate.validator.util.privilegedactions.SetAccessibility;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.wind.trademark.bill.dao.BillDao;
import com.wind.trademark.bill.model.BlBill;
import com.wind.trademark.bill.model.BlBillDetail;
import com.wind.trademark.bill.model.BlFee;
import com.wind.trademark.bill.service.BillService;
import com.wind.trademark.bill.vo.BillInfoVo;
import com.wind.trademark.bill.vo.BillVo4Detail;
import com.wind.trademark.bill.vo.BillVo4Fee;
import com.wind.trademark.common.dao.BaseDao;
import com.wind.trademark.common.exception.TmException;
import com.wind.trademark.common.vo.PageBean;
import com.wind.trademark.common.vo.PageParam;
import com.wind.trademark.task.model.TkTask;
@Service
public class BillServiceImpl implements BillService {
	@Autowired
	private BaseDao baseDao;
	@Autowired
	private BillDao billDao;
	@Override
	public PageBean queryBill(PageParam pageParam, Map<String, Object> params) {
		return billDao.queryBill(pageParam, params);
		
	}
	@Override
	public PageBean queryBillDetail(PageParam pageParam,
			Map<String, Object> params) {
		return billDao.queryBillDetail(pageParam, params);

	}
	@Override
	public PageBean queryFee(PageParam pageParam, Map<String, Object> params) {
		return billDao.queryFee(pageParam, params);

	}
	@Override
	public void deleteBillDetails(List<Long> ids) {
		billDao.deleteBillDetails(ids);

	}
	@Override
	public void deleteFees(List<Long> ids) {
		billDao.deleteFees(ids);
	}
	
	@Override
	public List<BillVo4Fee> queryBillVoAndItsFeeVo(Long taskId) {
		return billDao.queryBillVoAndItsFeeVo(taskId);
	}
	@Override
	public BlBill saveOrUpdateBill(BlBill blBill) {
		
		blBill.setCreateBy(1L);
		blBill.setLastUpdateBy(1L);
		blBill.setCreateTime(new Date());
		blBill.setLastUpdateTime(new Date());
		if(blBill.getId()==null){
			TkTask tkTask=this.baseDao.get(TkTask.class, blBill.getTaskId());
			blBill.setCode(this.genanteCode(tkTask));
			blBill.setStatus("NEW");
			blBill.setAmount(0.00);
		}
		 baseDao.saveOrUpdate(blBill);
		 return blBill;
	
	}
	private String genanteCode(TkTask tkTask) {
		DateFormat df=new SimpleDateFormat("yyMMddmms");
		String timeCode=df.format(new Date());
		return tkTask.getCtCompany().getCode()+"_"+timeCode;
	}
	@Override
	public List<BillVo4Detail> queryBillVoAndItsDetailVo(Long billId) {
		return billDao.queryBillVoAndItsDetailVo(billId);

	}
	@Override
	public BlBill loadBill(Long id) {
		return baseDao.get(BlBill.class, id);
	}
	@Override
	public BlBillDetail loadBillDetail(Long id) {
		return baseDao.get(BlBillDetail.class, id);

	}
	@Override
	public BlFee loadBlFee(Long id) {
		return baseDao.get(BlFee.class, id);

	}
	@Override
	public void deleteBillDetail(Long id) {
			baseDao.delete(this.baseDao.get(BlBillDetail.class, id));
	}
	@Override
	public void deleteBill(Long id) throws TmException {
		BlBill blBill=this.baseDao.get(BlBill.class, id);
		if(!"NEW".equals(blBill.getStatus())){
			throw new TmException("只有[草稿]状态的账单可以被删除");
		}
		//TODO detail 外键删除
		List<BlBillDetail> detailList=this.baseDao.findByProperty(BlBillDetail.class, "billId", id);
		for (BlBillDetail blBillDetail:detailList) {
			baseDao.delete(blBillDetail);
		}	
		baseDao.getHibernateTemplate().flush();
		baseDao.delete(blBill);

	}
	@Override
	public List<BlBillDetail> queryBlBillDetailByBillId(Long billId) {
		List<BlBillDetail> detailList=this.baseDao.findByProperty(BlBillDetail.class, "billId", billId);
		return detailList;
	}
	@Override
	public List<BlFee> queryBlFeelByBillId(Long billId) {
		List<BlFee> blFeeList=this.baseDao.findByProperty(BlFee.class, "billId", billId);
		return blFeeList;
	}
	@Override
	public List<BlBill> queryBlBillByTaskId(Long taskId) {
		List<BlBill> billList=this.baseDao.findByProperty(BlBill.class, "taskId", taskId);
		return billList;
	}
	@Override
	public BlBillDetail saveOrUpdateBlBillDetail(BlBillDetail blBillDetail) {
		blBillDetail.setCreateBy(1L);
		blBillDetail.setLastUpdateBy(1L);
		blBillDetail.setCreateTime(new Date());
		blBillDetail.setLastUpdateTime(new Date());

		 baseDao.saveOrUpdate(blBillDetail);
		 return blBillDetail;
	
	}
	@Override
	public BillInfoVo getBillInfo(Long billId) {
		return this.billDao.getBillInfo(billId);
	}
	@Override
	public Double getTotalAmountByBillId(Long billId) {
		return this.billDao.getTotalAmountByBillId(billId);
	}
	@Override
	public Double getPaidAmountByBillId(Long billId) {
		return this.billDao.getPaidAmountByBillId(billId);

	}
	@Override
	public BlFee saveOrUpdateBlFee(BlFee blFee) {

		blFee.setCreateBy(1L);
		blFee.setLastUpdateBy(1L);
		blFee.setCreateTime(new Date());
		blFee.setLastUpdateTime(new Date());

		 baseDao.saveOrUpdate(blFee);
		 return blFee;

	}
	@Override
	public BlBill changeBillStatus(Long billId, String status) throws TmException {
		BlBill blBill = this.loadBill(billId);
		if("OUT".equals(status)){
			Double total=this.getTotalAmountByBillId(billId);
			if(total==0){
				throw new TmException("该账单应收金额为 0,无法完成出账操作");
			}
			blBill.setChargeoffTime(new Date());
		}else if("PAID".equals(status)){
			Double total=this.getTotalAmountByBillId(billId);
			Double paid=this.getPaidAmountByBillId(billId);
			Double unPaid=total-paid;
			if(unPaid>0){
				throw new TmException("该账单存在未付款项,无法完成收讫操作");
			}
			blBill.setAmount(paid);
			blBill.setPaidTime(new Date());
		}else if("BAD".equals(status)){
			Double total=this.getTotalAmountByBillId(billId);
			Double paid=this.getPaidAmountByBillId(billId);
			Double unPaid=total-paid;
			if(unPaid<=0){
				throw new TmException("该账单不存在未付款项,无法完成坏账操作,请改用收讫操作");
			}
			blBill.setAmount(paid);
			//blBill.setChargeoffTime(new Date());
		}
		blBill.setStatus(status);
		this.baseDao.merge(blBill);
		return blBill;
	}



}
